package com.sky.service.impl;


import com.sky.entity.OrderDetail;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.vo.OrderReportVO;
import com.sky.vo.SalesTop10ReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
//        String beginStr = " 00:00:00";
//        String endStr = " 23:59:59";
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//        LocalDate beginTime = LocalDate.parse(begin, dateTimeFormatter);
//        LocalDate endTime = LocalDate.parse(end, dateTimeFormatter);
        List<LocalDate> dates = new ArrayList<>();
        List<Double> turnovers = new ArrayList<>();
        dates.add(begin);
        while (begin.isBefore(end)) {
            begin = begin.plusDays(1);//往后加一天
            dates.add(begin);
        }
        for (LocalDate date : dates) {
            LocalDateTime le = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime ri = LocalDateTime.of(date, LocalTime.MAX);
            Double turnover= orderMapper.getRurnoverByDate(le,ri);
            turnovers.add(turnover);
        }
//        String joinDateList = String.join(",", dateList);
//        String joinTurnoverList = String.join(",", turnoverList);
        String dateList = StringUtils.join(dates, ", ");
        String turnoverList = StringUtils.join(turnovers, ", ");
        return new TurnoverReportVO(dateList,turnoverList);
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dates = new ArrayList<>();
        List<Integer> totalUsers=new ArrayList<>();
        List<Integer> newUsers=new ArrayList<>();
        dates.add(begin);
        while (begin.isBefore(end)) {
            begin=begin.plusDays(1);
            dates.add(begin);
        }
        for (LocalDate date : dates) {
            LocalDateTime le = LocalDateTime.of(date, LocalTime.MIN);//得到一天的开始即 00：00：00
            LocalDateTime ri = LocalDateTime.of(date, LocalTime.MAX);//得到一天的结束即 23:59:59
            Integer totalUser=userMapper.getTotalUser(ri);
            Integer newUser = userMapper.getNewUser(le, ri);
            totalUsers.add(totalUser);
            newUsers.add(newUser);
        }
        String dateList = StringUtils.join(dates, ", ");
        String totalUsersList = StringUtils.join(totalUsers, ", ");
        String newUsersList = StringUtils.join(newUsers, ", ");
        return new UserReportVO(dateList,totalUsersList,newUsersList);
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dates = new ArrayList<>();
        List<Integer> orderCounts=new ArrayList<>();
        List<Integer> validOrderCounts=new ArrayList<>();
        dates.add(begin);
        while (begin.isBefore(end)) {
            begin=begin.plusDays(1);
            dates.add(begin);
        }
        for (LocalDate date : dates) {
            LocalDateTime le = LocalDateTime.of(date, LocalTime.MIN);//得到一天的开始即 00：00：00
            LocalDateTime ri = LocalDateTime.of(date, LocalTime.MAX);//得到一天的结束即 23:59:59
            Map<String, Object> map=new HashMap<>();
            map.put("le",le);
            map.put("ri",ri);
            Integer total= orderMapper.ordersStatistics(map);//每日订单总数
            map.put("status",5);
            Integer valid= orderMapper.ordersStatistics(map);//每日订单有效数量
            orderCounts.add(total);
            validOrderCounts.add(valid);
        }
        Map<String, Object> map=new HashMap<>();
        map.put("le",LocalDateTime.of(dates.get(0), LocalTime.MIN));
        map.put("ri",LocalDateTime.of(end, LocalTime.MAX));
        Integer total= orderMapper.ordersStatistics(map);//查询日期内的订单总数
        map.put("status",5);
        Integer valid= orderMapper.ordersStatistics(map);//查询日期内的订单有效数量
        double CompletionRate=0.0;
        //订单总数可能为0，此时计算会包异常
        if(total!=0){
            CompletionRate=valid*1.0/total;//完成率
        }
        String dateList = StringUtils.join(dates, ", ");
        String orderCountList = StringUtils.join(orderCounts, ", ");
        String validOrderCountList = StringUtils.join(validOrderCounts, ", ");
        return new OrderReportVO(dateList,orderCountList,validOrderCountList,total,valid,CompletionRate);
    }

    @Override
    public SalesTop10ReportVO top10Statistics(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        List<OrderDetail> orderDetailList= orderDetailMapper.getGoodsList(beginTime,endTime);
        //统计菜品的销量
        List<String> names=new ArrayList<>();
        List<Integer> saleCounts=new ArrayList<>();
        for (OrderDetail orderDetail : orderDetailList) {
            names.add(orderDetail.getName());
            saleCounts.add(orderDetail.getNumber());
        }
        String nameList = StringUtils.join(names, ", ");
        String saleCountList = StringUtils.join(saleCounts, ", ");
        return new SalesTop10ReportVO(nameList,saleCountList);
    }

    @Override
    public void exportData(HttpServletResponse response) throws IOException {
        //获取近30天的开始时间和结束时间
        LocalDate now = LocalDate.now();
        LocalDate last = now.plusDays(-30);
        List<LocalDate> dates = new ArrayList<>();
        dates.add(last);
        while (last.isBefore(now)) {
            last=last.plusDays(1);
            dates.add(last);
        }
        List<Double> turnovers = new ArrayList<>();//营业额集合
        List<Integer> validOrders=new ArrayList<>();//有效订单集合
        List<Double> completionRates=new ArrayList<>();//订单完成率集合
        List<Double> unitPrices=new ArrayList<>();//平均单价集合
        List<Integer> newUsers=new ArrayList<>();//新增用户集合
        List<Integer> totals=new ArrayList<>();//订单数集合
        for (LocalDate date : dates) {
            LocalDateTime begin = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime end = LocalDateTime.of(date, LocalTime.MAX);
            Double turnover = orderMapper.getRurnoverByDate(begin, end);//营业额
            Map<String,Object> map=new HashMap<>();
            map.put("le",begin);
            map.put("ri",end);
            Integer total = orderMapper.ordersStatistics(map);//订单数
            map.put("status",5);
            Integer valid= orderMapper.ordersStatistics(map);//有效订单
            Integer newUser = userMapper.getNewUser(begin, end);//新增用户
            double unitPrice=turnover/valid;//平均单价
            double completionRate=0.0;//订单完成率
            if(total!=null){
                completionRate=valid*1.0/total;
            }
            turnovers.add(turnover);
            validOrders.add(valid);
            completionRates.add(completionRate);
            newUsers.add(newUser);
            totals.add(total);
            unitPrices.add(unitPrice);
        }
        double turnoverAmount=turnovers.stream().reduce(0.0, Double::sum);//30天总营业额
        int totalAmount=totals.stream().reduce(0,Integer::sum);//30天总订单数
        int validAmount=validOrders.stream().reduce(0,Integer::sum);//30天总有效定单
        int newUserAmount =newUsers.stream().reduce(0,Integer::sum);//30天总新增用户数
        double unitPriceAmount=turnoverAmount/validAmount;//30天总平均单价
        double completionRateAmount=0.0;//30天总订单完成率
        if(totalAmount!=0){
            completionRateAmount=validAmount*1.0/totalAmount;
        }
        //获取输入流
        InputStream inputStream = Files.newInputStream(new File("F:\\javaClass\\my-takeout\\sky-server\\src\\main\\resources\\template\\运营数据报表模板.xlsx").toPath());
        //读取excel模板文件
        try {
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet1 = workbook.getSheet("sheet1");//获取标签页
            //填充概览数据
            sheet1.getRow(1).getCell(1).setCellValue("时间："+last+"——"+now);//将时间段填充到第二行的第二个单元格
            sheet1.getRow(3).getCell(2).setCellValue(totalAmount);//填充概览中的营业额
            sheet1.getRow(3).getCell(4).setCellValue(completionRateAmount);//填充概览中的完成率
            sheet1.getRow(3).getCell(6).setCellValue(newUserAmount);//填充概览中的用户数
            sheet1.getRow(4).getCell(2).setCellValue(validAmount);//填充概览中的有效定单
            sheet1.getRow(4).getCell(4).setCellValue(unitPriceAmount);//填充概览中的平均单价
            //填充明细数据
            for (int i = 0,row=7; i < dates.size(); i++,row++) {
                XSSFRow sheet1Row = sheet1.getRow(row);//获取行
                sheet1Row.getCell(1).setCellValue(dates.get(0).toString());//填充日期
                sheet1Row.getCell(2).setCellValue(turnovers.get(i));//填充营业额
                sheet1Row.getCell(3).setCellValue(validOrders.get(i));//填充有效单数
                sheet1Row.getCell(4).setCellValue(completionRates.get(i));//填充订单完成率
                sheet1Row.getCell(5).setCellValue(unitPrices.get(i));//填充平均单价
                sheet1Row.getCell(6).setCellValue(newUsers.get(i));//填充新增用户数
            }
            //通过输出流下载到浏览器
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            //关闭资源
            workbook.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
